/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import {
  h,
  ref,
  PropType,
  computed,
  defineComponent,
  resolveComponent,
} from 'vue';
import { useNamespace } from '@ibiz-template/vue3-util';
import {
  IModal,
  ValueOP,
  IFilterNodeField,
  SearchBarFilterController,
} from '@ibiz-template/runtime';
import { EhrSearchBarController } from '../../ehr-search-bar.controller';
import './search-bar.scss';

const FilterModes = [
  { valueOP: ValueOP.EQ, label: '等于(=)' },
  { valueOP: ValueOP.NOT_EQ, label: '不等于(<>)' },
  { valueOP: ValueOP.GT, label: '大于(>)' },
  { valueOP: ValueOP.GT_AND_EQ, label: '大于等于(>=)' },
  { valueOP: ValueOP.LT, label: '小于(<)' },
  { valueOP: ValueOP.LT_AND_EQ, label: '小于等于(<=)' },
  { valueOP: ValueOP.IS_NULL, label: '值为空(Nil)' },
  { valueOP: ValueOP.IS_NOT_NULL, label: '值不为空(NotNil)' },
  { valueOP: ValueOP.IN, label: '值在范围中(In)' },
  { valueOP: ValueOP.NOT_IN, label: '值不在范围中(NotIn)' },
  { valueOP: ValueOP.LIKE, label: '文本包含(%)' },
  { valueOP: ValueOP.LIFT_LIKE, label: '文本左包含(%#)' },
  { valueOP: ValueOP.RIGHT_LIKE, label: '文本右包含(#%)' },
  { valueOP: ValueOP.EXISTS, label: '存在(EXISTS)' },
  { valueOP: ValueOP.NOT_EXISTS, label: '不存在(NOTEXISTS)' },
] as const;

export const ExcludeOPs: readonly string[] = [
  ValueOP.IS_NULL,
  ValueOP.IS_NOT_NULL,
  ValueOP.EXISTS,
  ValueOP.NOT_EXISTS,
] as const;

export const SearchBar = defineComponent({
  name: 'SearchBar',
  props: {
    controller: {
      type: Object as PropType<EhrSearchBarController>,
      required: true,
    },
    modal: { type: Object as PropType<IModal> },
  },
  setup(props) {
    const ns = useNamespace('search-bar');
    const c = props.controller;

    const query = ref<string>('');

    const activeNames = ref<number[]>([]);

    const filterName = ref<string>('');

    const visible = ref<boolean>(false);

    const filterNodes = computed(() => {
      return (c.state.filterNodes[0]?.children || []) as IFilterNodeField[];
    });

    const visibleTabs = computed(() => {
      return c.state.filterGroups.some(filter => filter.visible);
    });

    const num = computed(() => {
      return (c.state.filterNodes[0]?.children || []).length;
    });

    /**
     * @description 值条件改变
     * @param {IFilterNodeField} node
     * @param {ValueOP} valueOP
     */
    const onValueOPSelect = (node: IFilterNodeField, valueOP: ValueOP) => {
      node.valueOP = valueOP;
      node.value = null;
    };

    /**
     * @description Popover 显示
     */
    const onPopoverShow = () => {
      query.value = '';
      activeNames.value = [...Array(c.state.filterItemGroups.length).keys()];
    };

    /**
     * @description
     * @param {boolean} [isSave=false]
     */
    const onClosePopover = async (isSave: boolean = false) => {
      if (isSave) {
        await c.onSaveFilter(filterName.value);
      }
      visible.value = false;
      filterName.value = '';
    };

    /**
     * @description 绘制编辑器
     * @param {IFilterNodeField} node
     * @param {SearchBarFilterController} nodeC
     * @returns {*}
     */
    const renderEditor = (
      node: IFilterNodeField,
      nodeC: SearchBarFilterController,
    ) => {
      if (
        !nodeC.editor ||
        !nodeC.editorProvider ||
        (node.valueOP && ExcludeOPs.includes(node.valueOP))
      )
        return null;
      const { data, value } = nodeC.calcEditorProps(node);
      return (
        <div class={ns.em('filter-node', 'editor')}>
          {h(resolveComponent(nodeC.editorProvider.formEditor), {
            data,
            value,
            disabled: node.disabled,
            controller: nodeC.editor,
            key: nodeC.editor.model.id,
            onChange: (val: unknown, name?: string): void => {
              nodeC.onEditorChange(node, val, name);
              c.onSearch();
            },
          })}
        </div>
      );
    };

    /**
     * @description 绘制内容区
     * @returns {*}
     */
    const renderContent = () => {
      return (
        <div class={ns.e('content')}>
          {filterNodes.value.map(node => {
            if (node.nodeType !== 'FIELD') return;
            const nodeC = c.findFilterControllerByNode(node);
            if (!nodeC) return;
            const valueOPs = FilterModes.filter(mode => {
              if (nodeC.valueOP) return mode.valueOP === nodeC.valueOP;
              return true;
            });
            return (
              <div class={ns.e('filter-node')}>
                <div class={ns.em('filter-node', 'header')}>
                  <div class={ns.em('filter-node', 'label')}>{nodeC.label}</div>
                  <ion-icon
                    title='删除'
                    name='close-outline'
                    class={ns.em('filter-node', 'remove')}
                    onClick={() => c.handleFilterItemChange(nodeC.key, false)}
                  ></ion-icon>
                </div>
                <el-select
                  disabled={node.disabled || nodeC.valueOP}
                  model-value={node.valueOP}
                  class={ns.em('filter-node', 'op-select')}
                  onChange={(value: ValueOP) => onValueOPSelect(node, value)}
                >
                  {valueOPs.map(mode => {
                    return (
                      <el-option
                        label={mode.label}
                        key={mode.valueOP}
                        value={mode.valueOP}
                      />
                    );
                  })}
                </el-select>
                {renderEditor(node, nodeC)}
              </div>
            );
          })}
        </div>
      );
    };

    /**
     * @description 绘制过滤组
     * @returns {*} 
     */
    const renderTabs = () => {
      if (visibleTabs.value)
        return (
          <el-tabs
            class={ns.e('tabs')}
            v-model={c.state.activeGroup}
            onTabChange={() => c.onSearch()}
          >
            {c.state.filterGroups.map(filter => {
              if (filter.visible)
                return (
                  <el-tab-pane name={filter.key}>
                    {{
                      label: () => (
                        <el-card
                          class={ns.e('tab-item')}
                          title={filter.caption}
                        >
                          {filter.counterId && (
                            <div class={ns.em('tab-item', 'counter')}>
                              {filter.count}
                            </div>
                          )}
                          <span class={ns.em('tab-item', 'caption')}>
                            {filter.caption}
                          </span>
                        </el-card>
                      ),
                    }}
                  </el-tab-pane>
                );
              return null;
            })}
          </el-tabs>
        );
    };

    /**
     * @description 绘制头部区域
     * @returns {*}
     */
    const renderHeader = () => {
      return (
        <div class={ns.e('header')}>
          {renderTabs()}
          <div class={ns.em('header', 'title')}>筛选条件</div>
          <el-select
            clearable
            placeholder={
              c.state.filters.length === 0
                ? '暂无已保存的筛选条件'
                : '选择已保存的筛选条件'
            }
            class={ns.em('header', 'select')}
            popperClass={ns.e('filter-select')}
            model-value={c.state.activeFilter}
            disabled={c.state.filters.length === 0}
            onChange={(value: string) => c.handleFilterChange(value)}
          >
            {c.state.filters.map(filter => {
              return (
                <el-option
                  key={filter.key}
                  value={filter.key}
                  label={filter.caption}
                  class={ns.em('filter-select', 'item')}
                >
                  <div>{filter.caption}</div>
                  <ion-icon
                    title='删除'
                    name='close-outline'
                    class={ns.em('filter-select', 'remove')}
                    onClick={(evt: MouseEvent) => {
                      evt.stopPropagation();
                      c.onRemoveFilter(filter.key);
                    }}
                  ></ion-icon>
                </el-option>
              );
            })}
          </el-select>
          <div class={ns.em('header', 'actions')}>
            <el-popover
              trigger='click'
              placement='bottom'
              class={ns.e('popover')}
              v-model:visible={visible.value}
            >
              {{
                reference: () => <el-button type='text'>保存</el-button>,
                default: () => {
                  return (
                    <div class={ns.em('popover', 'content')}>
                      <el-input
                        placeholder='筛选条件名称'
                        v-model={filterName.value}
                        class={ns.em('popover', 'filter-name')}
                      />
                      <div class={ns.em('popover', 'actions')}>
                        <el-button
                          type='text'
                          disabled={!filterName.value}
                          onClick={() => onClosePopover(true)}
                        >
                          确认
                        </el-button>
                        <el-button type='text' onClick={() => onClosePopover()}>
                          取消
                        </el-button>
                      </div>
                    </div>
                  );
                },
              }}
            </el-popover>
            <el-button type='text' onClick={() => c.onReset()}>
              还原
            </el-button>
          </div>
        </div>
      );
    };

    /**
     * @description 绘制底部区域
     * @returns {*}
     */
    const renderFooter = () => {
      return (
        <div class={ns.e('footer')}>
          <el-popover
            width={200}
            placement='top'
            trigger='click'
            class={ns.e('popover')}
            popperStyle={{ height: '360px' }}
            onShow={() => onPopoverShow()}
          >
            {{
              reference: () => (
                <el-button type='text'>
                  <ion-icon name='add-outline'></ion-icon>添加筛选项
                </el-button>
              ),
              default: () => {
                return (
                  <div class={ns.em('popover', 'content')}>
                    <el-input
                      placeholder='搜索'
                      v-model={query.value}
                      class={ns.em('popover', 'search')}
                    >
                      {{
                        suffix: () => (
                          <ion-icon name='search-outline'></ion-icon>
                        ),
                      }}
                    </el-input>
                    <el-collapse
                      v-model={activeNames.value}
                      class={ns.em('popover', 'collapse')}
                    >
                      {c.state.filterItemGroups.map((group, index) => {
                        return (
                          <el-collapse-item name={index} title={group.caption}>
                            {group.children.map(child => {
                              if (
                                query.value &&
                                !child.caption.includes(query.value)
                              )
                                return;
                              return (
                                <el-checkbox
                                  class={ns.em('popover', 'filter')}
                                  label={child.caption}
                                  model-value={child.selected}
                                  onChange={(val: boolean) =>
                                    c.handleFilterItemChange(child.key, val)
                                  }
                                />
                              );
                            })}
                          </el-collapse-item>
                        );
                      })}
                    </el-collapse>
                  </div>
                );
              },
            }}
          </el-popover>
        </div>
      );
    };

    /**
     * @description 绘制顶部
     * @returns {*}
     */
    const renderTop = () => {
      if (!props.modal) return;
      return (
        <div class={ns.e('top')}>
          <div class={ns.em('top', 'title')}>
            <ion-icon name='filter-circle'></ion-icon>
            {c.model.logicName}
            <sup class={ns.em('top', 'counter')}>{num.value}</sup>
          </div>
          <ion-icon
            title='关闭'
            name='close-outline'
            class={ns.em('top', 'close')}
            onClick={(evt: MouseEvent) => props.modal!.dismiss()}
          ></ion-icon>
        </div>
      );
    };

    return {
      c,
      ns,
      renderTop,
      renderHeader,
      renderContent,
      renderFooter,
    };
  },
  render() {
    return (
      <div class={this.ns.b()}>
        {this.renderTop()}
        {this.renderHeader()}
        {this.renderContent()}
        {this.renderFooter()}
      </div>
    );
  },
});
